package cn.gov.cus.rmftquartz.service.entry;

import cn.gov.cus.rmftquartz.entity.ManifestChkNewVo;
import cn.gov.cus.rmftquartz.entity.RskEntryVo;
import cn.gov.cus.rmftquartz.mappers.h2000.ManifestChkNewMapper;
import cn.gov.cus.rmftquartz.mappers.oracle.EntryMapper;
import com.github.pagehelper.PageHelper;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.transaction.SystemException;
import javax.transaction.TransactionManager;
import java.text.DecimalFormat;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * @author wxming.
 * @date 2018/2/11.
 */
@Service
public class ScheduledEntryService {
    /**
     * 报关单扫描接口表一次获取最大条数。
     */
    private int entryNumber=1000;
    /**
     * 报关单只处理公路舱单数据，多种用英文逗号隔开：4,5,6。
     */
    @Value("${entryData}")
    private String entryData;
    /**
     * 同一个数据库中，ORCL这种实例或者库的域得一样，不只是Ip，但是用户名不一样时，可以通过“用户名.表名”跟配置的数据源里的表联查。（该框架通过mapper目录确定是哪个数据源。）
     */
    @Value("${datasource.oracle.mft.username}")
    private String h2000ChkNewUser;
    @Autowired
    private ManifestChkNewMapper manifestChkNewMapper;
    @Autowired
    private EntryMapper entryMapper;


    @Autowired
    private TransactionManager transactionManager;




    //没用分布式事务之前的那种数据源config配置，单个数据源的事务可以这样写(两种都行），其中transactionManager的值对应的
    // 是配置类里写的事务管理类的bean名,如果没有写，默认是主数据源的事务管理，只能回滚主数据源的。
    // 要想让不同数据源的都回滚，在不用分布式事务的情况下，可以将不同数据源的方法写在不同service方法中，
    // 这样逐个传递异常，应该也能都让回滚了。（实验证实，多米诺式的方式事务只有第一个能回滚，中间的不能。）
    //@Transactional(transactionManager = "gbaseTransactionManager",rollbackFor = Exception.class)
    //@Transactional(value = "gbaseTransactionManager",rollbackFor = {Exception.class})
    public List<ManifestChkNewVo> getEntry() {
        ManifestChkNewVo vo = new ManifestChkNewVo();
        vo.setH2000ChkNewUser(h2000ChkNewUser);
        vo.setEntryData(entryData);
        //要利用分页插件来分批查询数据直接写下面一句代码，并且List中的类继承了BaseEntity就行。
        PageHelper.startPage(1,entryNumber);
        //直接return后面的Mapper调方法的结果的话会有问题，得先拿个list变量在上面这个分页插件处接了，再把接到的list进行return才行。
        List<ManifestChkNewVo> list = manifestChkNewMapper.doSelect(vo);
        return list;
    }

    //编程式分布式事务例子；需注入TransactionManager。
    public void demoTransactionManager() throws SystemException {
        try{
            transactionManager.begin();
            /*...
            调不同数据源的mapper给数据库写入数据做了一通操作。*/
            transactionManager.commit();
        }catch (Exception e){
            transactionManager.rollback();
        }
    }

    /**
     * 调用存储过程，修改rskid2000
     * @param list
     */
    public void setH2000Counter(List<RskEntryVo> list){
        SimpleDateFormat sdf = new SimpleDateFormat("YY");
        DecimalFormat df = new DecimalFormat("00000000");
        String year = sdf.format(new Date());
        Map<String,Object> map;
        String customsCode;
        int index;
        for (RskEntryVo vo:list){
            map= new HashMap<>(16);
            customsCode=vo.getRskId();
            map.put("type","L");
            map.put("customsCode",customsCode);
            map.put("iEFlag",vo.getRskAge());
            entryMapper.getCounter(map);
            index = (int)map.get("nCounter");//上行调用存储过程的代码将返回结果nCounter在传过去的map里。
            vo.setRskName("L"+year+customsCode+df.format(index));

        }
    }

}
